package com.yunquan.ohana.utils

import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import kotlin.random.Random


/**
 * $
 *
 * @author yjp
 * @date 2021-06-08 16:24
 */
class CodeUtils {
    companion object {
        /**
         * 随机数数组
         * 去除了易混淆的 数字 0 和 字母 o O
         * 数字 1 和 字母 i I l L
         * 数字 6 和 字母 b
         * 数字 9 和 字母 q
         * 字母 c C 和 G
         * 字母 t （经常和随机线混在一起看不清）
         */
        private val CHARS = charArrayOf(
            '1', '2', '3', '4', '5', '7', '8', '9'/*,
            'a', 'd', 'e', 'f', 'g', 'h', 'j', 'k', 'm',
            'n', 'p', 'r', 's', 'u', 'v', 'w', 'x', 'y', 'z',
            'A', 'B', 'D', 'E', 'F', 'H', 'J', 'K', 'M',
            'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'*/
        )

        //default settings
        //验证码默认随机数的个数
        private const val DEFAULT_CODE_LENGTH = 4

        //默认字体大小
        private const val DEFAULT_FONT_SIZE = 26

        //默认线条的条数
        private const val DEFAULT_LINE_NUMBER = 2

        //padding值
        private const val BASE_PADDING_LEFT = 10  //padding值
        private const val RANGE_PADDING_LEFT = 15  //padding值
        private const val BASE_PADDING_TOP = 15  //padding值
        private const val RANGE_PADDING_TOP = 20

        //验证码的默认宽高
        private const val DEFAULT_WIDTH = 100  //验证码的默认宽高
        private const val DEFAULT_HEIGHT = 40

        //settings decided by the layout xml
        //canvas width and height
        private const val width = DEFAULT_WIDTH //settings decided by the layout xml

        //canvas width and height
        private const val height = DEFAULT_HEIGHT

        //random word space and pading_top
        private const val base_padding_left = BASE_PADDING_LEFT  //random word space and pading_top
        private const val range_padding_left = RANGE_PADDING_LEFT

        //random word space and pading_top
        private const val base_padding_top = BASE_PADDING_TOP  //random word space and pading_top
        private const val range_padding_top = RANGE_PADDING_TOP


        val instance by lazy(LazyThreadSafetyMode.SYNCHRONIZED) { CodeUtils() }
    }

    //number of chars, lines; font size
    private val codeLength = DEFAULT_CODE_LENGTH  //number of chars, lines; font size
    private val lineNumber = DEFAULT_LINE_NUMBER  //number of chars, lines; font size
    private val fontSize = DEFAULT_FONT_SIZE

    //variables
    private var code: String? = null
    private var paddingLeft = 0
    private var paddingTop = 0

    //验证码图片
    fun createBitmap(isLine:Boolean): Bitmap? {
        paddingLeft = 0
        val bp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
        val c = Canvas(bp)
        code = createCode()
//        c.drawColor(Color.WHITE)
        val paint = Paint()
        paint.isAntiAlias = true
        paint.textSize = fontSize.toFloat()
        //画验证码
        for (element in code!!) {
            randomTextStyle(paint)
            randomPadding()
            c.drawText(
                element.toString() + "",
                paddingLeft.toFloat(),
                paddingTop.toFloat(),
                paint
            )
        }
        if (isLine) {
            //画线条
            for (i in 0 until lineNumber) {
                drawLine(c, paint)
            }
        }
        c.save() //保存
        c.restore() //
        return bp
    }

    fun getCode(): String? {
        return code
    }

    //生成验证码
    private fun createCode(): String {
        val buffer = StringBuilder()
        for (i in 0 until codeLength) {
            buffer.append(CHARS[Random.nextInt(CHARS.size)])
        }
        return buffer.toString()
    }

    //画干扰线
    private fun drawLine(canvas: Canvas, paint: Paint) {
        val color = randomColor()
        val startX: Int = Random.nextInt(width)
        val startY: Int = Random.nextInt(height)
        val stopX: Int = Random.nextInt(width)
        val stopY: Int = Random.nextInt(height)
        paint.strokeWidth = 1f
        paint.color = color
        canvas.drawLine(startX.toFloat(), startY.toFloat(), stopX.toFloat(), stopY.toFloat(), paint)
    }

    //生成随机颜色
    private fun randomColor(): Int {
        return randomColor(1)
    }

    private fun randomColor(rate: Int): Int {
        val red: Int = Random.nextInt(256) / rate
        val green: Int = Random.nextInt(256) / rate
        val blue: Int = Random.nextInt(256) / rate
        return Color.rgb(red, green, blue)
    }

    //随机生成文字样式，颜色，粗细，倾斜度
    private fun randomTextStyle(paint: Paint) {
        val color = randomColor()
        paint.color = color
        paint.isFakeBoldText = Random.nextBoolean() //true为粗体，false为非粗体
//        var skewX: Float = Random.nextInt(11).toFloat() / 10
//        skewX = if (Random.nextBoolean()) skewX else -skewX
//        paint.textSkewX = skewX //float类型参数，负数表示右斜，整数左斜
        //paint.setUnderlineText(true); //true为下划线，false为非下划线
        //paint.setStrikeThruText(true); //true为删除线，false为非删除线
    }

    //随机生成padding值
    private fun randomPadding() {
        paddingLeft += base_padding_left + Random.nextInt(range_padding_left)
        paddingTop = range_padding_top
//        padding_top = base_padding_top + Random.nextInt(range_padding_top)
    }
}